// Copyright (c) 2022 NetEase, Inc. All rights reserved.
// Use of this source code is governed by a MIT license that can be
// found in the LICENSE file.

package com.netease.yunxin.kit.entertainment.common.permission;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Build;
import androidx.annotation.ChecksSdkIntAtLeast;
import androidx.fragment.app.Fragment;
import com.netease.yunxin.kit.entertainment.common.permission.annotation.OnMPermissionDenied;
import com.netease.yunxin.kit.entertainment.common.permission.annotation.OnMPermissionGranted;
import com.netease.yunxin.kit.entertainment.common.permission.annotation.OnMPermissionNeverAskAgain;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public final class MPermissionUtil {

  @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.M)
  public static boolean isOverMarshmallow() {
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
  }

  public static Activity getActivity(Object object) {
    if (object instanceof Fragment) {
      return ((Fragment) object).getActivity();
    } else if (object instanceof Activity) {
      return (Activity) object;
    }
    return null;
  }

  @TargetApi(value = Build.VERSION_CODES.M)
  public static List<String> findDeniedPermissions(Activity activity, String... permission) {
    List<String> denyPermissions = new ArrayList<>();
    for (String value : permission) {
      if (activity.checkSelfPermission(value) != PackageManager.PERMISSION_GRANTED) {
        denyPermissions.add(value);
      }
    }
    return denyPermissions;
  }

  @TargetApi(value = Build.VERSION_CODES.M)
  public static List<String> findNeverAskAgainPermissions(Activity activity, String... permission) {
    List<String> neverAskAgainPermission = new ArrayList<>();
    for (String value : permission) {
      if (activity.checkSelfPermission(value) != PackageManager.PERMISSION_GRANTED
          && !activity.shouldShowRequestPermissionRationale(value)) {
        neverAskAgainPermission.add(value);
      }
    }

    return neverAskAgainPermission;
  }

  @TargetApi(value = Build.VERSION_CODES.M)
  public static List<String> findDeniedPermissionWithoutNeverAskAgain(
      Activity activity, String... permission) {
    List<String> denyPermissions = new ArrayList<>();
    for (String value : permission) {
      if (activity.checkSelfPermission(value) != PackageManager.PERMISSION_GRANTED
          && activity.shouldShowRequestPermissionRationale(value)) {
        denyPermissions.add(value);
      }
    }

    return denyPermissions;
  }

  @TargetApi(value = Build.VERSION_CODES.M)
  public static boolean hasNeverAskAgainPermission(Activity activity, List<String> permission) {
    for (String value : permission) {
      if (activity.checkSelfPermission(value) != PackageManager.PERMISSION_GRANTED
          && !activity.shouldShowRequestPermissionRationale(value)) {
        return true;
      }
    }

    return false;
  }

  public static <A extends Annotation> Method findMethodWithRequestCode(
      Class clazz, Class<A> annotation, int requestCode) {
    for (Method method : clazz.getDeclaredMethods()) {
      if (method.isAnnotationPresent(annotation)) {
        if (isEqualRequestCodeFromAnnotation(method, annotation, requestCode)) {
          return method;
        }
      }
    }
    return null;
  }

  public static boolean isEqualRequestCodeFromAnnotation(Method m, Class clazz, int requestCode) {
    if (clazz.equals(OnMPermissionDenied.class)) {
      return requestCode == m.getAnnotation(OnMPermissionDenied.class).value();
    } else if (clazz.equals(OnMPermissionGranted.class)) {
      return requestCode == m.getAnnotation(OnMPermissionGranted.class).value();
    } else if (clazz.equals(OnMPermissionNeverAskAgain.class)) {
      return requestCode == m.getAnnotation(OnMPermissionNeverAskAgain.class).value();
    } else {
      return false;
    }
  }

  public static String toString(List<String> permission) {
    if (permission == null || permission.isEmpty()) {
      return "";
    }

    return toString(permission.toArray(new String[permission.size()]));
  }

  public static String toString(String[] permission) {
    if (permission == null || permission.length <= 0) {
      return "";
    }

    StringBuilder sb = new StringBuilder();
    for (String p : permission) {
      sb.append(p.replaceFirst("android.permission.", ""));
      sb.append(",");
    }

    sb.deleteCharAt(sb.length() - 1);

    return sb.toString();
  }
}
